package com.crazy.web.service.share.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crazy.model.custom.mapper.IArticleLabelMapper;
import com.crazy.model.major.dto.ArticleDto;
import com.crazy.model.major.entity.TArticle;
import com.crazy.model.major.entity.TLabel;
import com.crazy.model.major.entity.TLabelArticleRelation;
import com.crazy.model.major.service.TArticleService;
import com.crazy.model.major.service.TLabelArticleRelationService;
import com.crazy.model.major.service.TLabelService;
import com.crazy.web.service.share.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author zhaochaofeng
 * @version 1.0
 * @date 2020/12/1 9:39
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private TArticleService tArticleService;
    @Autowired
    private TLabelService tLabelService;
    @Autowired
    private TLabelArticleRelationService tLabelArticleRelationService;
    @Autowired
    private IArticleLabelMapper articleLabelMapper;

    @Override
    public IPage<TArticle> find(long userId, long page, long rows, String search) {
        QueryWrapper<TArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(TArticle.Columns.valid, 1);
        queryWrapper.eq(TArticle.Columns.userId, userId);
        if(StrUtil.isNotEmpty(search)){
            queryWrapper.like(TArticle.Columns.titleName, search);
        }
        queryWrapper.orderByDesc(TArticle.Columns.id);
        Page<TArticle> articlePage = new Page<TArticle>(page, rows);
        IPage<TArticle> articleIPage = tArticleService.page(articlePage, queryWrapper);
        List<TArticle> articleList = articleIPage.getRecords();
        List articleDtos = new ArrayList();
        for(TArticle article : articleList){
            ArticleDto articleDto = new ArticleDto();
            BeanUtil.copyProperties(article, articleDto);
            List<TLabel> labels = articleLabelMapper.getLabelByArticleId(articleDto.getId());
            AtomicReference<String> labelNames = new AtomicReference<>("");
            labels.stream().map(TLabel::getLabelName).forEach(s -> {
                labelNames.set(labelNames + s + ",");
            });
            if(labelNames.get().endsWith(",")){
                articleDto.setLabelNames(labelNames.get().substring(0, labelNames.get().length()-1));
            }else{
                articleDto.setLabelNames(labelNames.get());
            }
            articleDtos.add(articleDto);
        }
        articleIPage.setRecords(articleDtos);
        return articleIPage;
    }

    @Override
    public TArticle findByIdWithAuthority(long userId, long id) {
        TArticle tArticle = tArticleService.getById(id);
        if(tArticle.getUserId().equals(userId)){
            return tArticle;
        }else{
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(TArticle tArticle, long userId) {
        if(tArticle.getId()==null)
        {
            tArticle.setCreateTime(LocalDateTime.now());
            tArticle.setUpdateTime(LocalDateTime.now());
            tArticle.setUserId(userId);
            tArticleService.save(tArticle);
        }else{
            TArticle localArticle = tArticleService.getById(tArticle.getId());
            if(localArticle.getUserId().equals(userId)){
                tArticle.setUpdateTime(LocalDateTime.now());
                tArticleService.updateById(tArticle);
            }else{
                throw new ValidateException("没有修改权限");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(TArticle tArticle, long userId, String[] labelNames) {
        if(tArticle.getId()==null)
        {
            tArticle.setCreateTime(LocalDateTime.now());
            tArticle.setUpdateTime(LocalDateTime.now());
            tArticle.setUserId(userId);
            tArticleService.save(tArticle);
        }else{
            TArticle localArticle = tArticleService.getById(tArticle.getId());
            if(localArticle.getUserId().equals(userId)){
                tArticle.setUpdateTime(LocalDateTime.now());
                tArticleService.updateById(tArticle);
            }else{
                throw new ValidateException("没有修改权限");
            }
            //删除历史的文章标签关联数据
            QueryWrapper<TLabelArticleRelation> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(TLabelArticleRelation.Columns.articleId, tArticle.getId());
            List<TLabelArticleRelation> labelArticleRelations = tLabelArticleRelationService.list(queryWrapper);
            for(TLabelArticleRelation labelArticleRelation : labelArticleRelations){
                tLabelArticleRelationService.removeById(labelArticleRelation.getId());
            }
        }

        //通过labelName和userId获取label
        Arrays.asList(labelNames).stream().forEach(c -> {
            QueryWrapper<TLabel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(TLabel.Columns.valid, 1);
            queryWrapper.eq(TLabel.Columns.userId, userId);
            queryWrapper.eq(TLabel.Columns.labelName, c);
            List<TLabel> list = tLabelService.list(queryWrapper);
            if(list.size()>0){
                long id = list.get(0).getId();
                TLabelArticleRelation tLabelArticleRelation = new TLabelArticleRelation();
                tLabelArticleRelation.setArticleId(tArticle.getId());
                tLabelArticleRelation.setLabelId(id);
                tLabelArticleRelationService.save(tLabelArticleRelation);
            }
        });

    }

    @Override
    public void delete(Long[] ids) {
        Arrays.asList(ids).stream().forEach(c -> {
            TArticle tArticle = tArticleService.getById(c);
            tArticle.setValid(0);
            tArticleService.updateById(tArticle);
        });
    }

    @Override
    public void hasRead(Long articleId) {
        TArticle tArticle = tArticleService.getById(articleId);
        tArticle.setReadTimes(tArticle.getReadTimes()+1);
        tArticleService.updateById(tArticle);
    }

}
